/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.rs.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.xy.biz.fd.client.DocumentClient;
import com.xy.biz.fd.client.RepositoryClient;
import com.xy.biz.fd.domain.req.document.GetDocumentRequest;
import com.xy.biz.fd.domain.req.repository.GetRepositoryRequest;
import com.xy.biz.fd.domain.resp.GetDocumentResponse;
import com.xy.biz.fd.domain.resp.GetRepositoryResponse;
import com.xy.biz.rs.domain.bo.RecordTemplateUserGroupBO;
import com.xy.biz.rs.domain.constants.RecordTemplateConstants;
import com.xy.biz.rs.domain.converter.RecordTemplateConverter;
import com.xy.biz.rs.domain.po.RecordTemplatePO;
import com.xy.biz.rs.domain.query.RecordTemplateUserGroupQuery;
import com.xy.biz.rs.domain.req.AppointUpdaterRequest;
import com.xy.biz.rs.domain.req.SaveRecordTemplateRequest;
import com.xy.biz.rs.domain.req.UpdateRecordTemplateRequest;
import com.xy.biz.rs.domain.resp.GetRecordTemplateResponse;
import com.xy.biz.rs.manager.RecordTemplateUserGroupManager;
import com.xy.biz.uc.client.UserClient;
import com.xy.biz.uc.client.UserGroupClient;
import com.xy.tool.context.UserContextHolder;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xy.lang.domain.Result;
import com.xy.biz.rs.domain.bo.RecordTemplateBO;
import com.xy.biz.rs.domain.query.RecordTemplateQuery;
import com.xy.biz.rs.service.RecordTemplateService;
import com.xy.biz.rs.manager.RecordTemplateManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

/**
 *
 *
 * @author wwj
 * @date 2021-4-9
 */
@Service
public class RecordTemplateServiceImpl implements RecordTemplateService {

	@Autowired
	private RecordTemplateManager recordTemplateManager;
	@Autowired
	private RecordTemplateUserGroupManager recordTemplateUserGroupManager;
	@Autowired
	private UserGroupClient userGroupClient;
	@Autowired
	private UserClient userClient;
	@Autowired
	private DocumentClient documentClient;
	@Autowired
	private RepositoryClient repositoryClient;

	@Transactional
	@Override
	public Result<?> saveRecordTemplate(SaveRecordTemplateRequest request) {
		RecordTemplateBO recordTemplateBO = RecordTemplateConverter.toBO(request);
		buildSaveBO(recordTemplateBO);
		RecordTemplatePO recordTemplatePO = recordTemplateManager.saveRecordTemplate(recordTemplateBO);
		if (!ObjectUtils.isEmpty(recordTemplatePO)) {
			saveRecordTemplateUserGroups(recordTemplatePO.getRecordTemplateId(),request.getUserGroupIdList());
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	private void buildSaveBO(RecordTemplateBO recordTemplateBO) {
		recordTemplateBO.setCreateTime(LocalDateTime.now());
		recordTemplateBO.setCreateUserId(UserContextHolder.getUserId());
		recordTemplateBO.setDeleteFlag(false);
		recordTemplateBO.setStatus(RecordTemplateConstants.TEMPLATE_STATUS_NOT_ACTIVE);
		recordTemplateBO.setTenantId(UserContextHolder.getTenantId());
		recordTemplateBO.setUpdateTime(LocalDateTime.now());
		recordTemplateBO.setUpdateUserId(UserContextHolder.getUserId());
	}

	@Override
	public Result<?> saveAllRecordTemplate(Collection<RecordTemplateBO> collection) {
		int affectedRows = recordTemplateManager.saveAllRecordTemplate(collection);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Transactional
	@Override
	public Result<?> updateRecordTemplate(UpdateRecordTemplateRequest request) {
		RecordTemplateBO recordTemplateBO = RecordTemplateConverter.toBO(request);
		recordTemplateBO.setStatus(RecordTemplateConstants.TEMPLATE_STATUS_MOTIFY);
		int affectedRows = recordTemplateManager.updateRecordTemplate(recordTemplateBO);
		if (affectedRows > 0) {
			recordTemplateUserGroupManager.deleteRecordTemplateUserGroupByRecordTemplateId(request.getRecordTemplateId());
			saveRecordTemplateUserGroups(request.getRecordTemplateId(),request.getUserGroupIdList());
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	private void saveRecordTemplateUserGroups(Long recordTemplateId,List<Long> userGroupIdList) {
		ArrayList<RecordTemplateUserGroupBO> list = new ArrayList<>();
		for (Long userGroupId : userGroupIdList) {
			RecordTemplateUserGroupBO rtugb = RecordTemplateUserGroupBO.builder().printCount(0)
					.recordTemplateId(recordTemplateId)
					.tenantId(0L)
					.userGroupId(userGroupId).build();
			list.add(rtugb);
		}
		recordTemplateUserGroupManager.saveAllRecordTemplateUserGroup(list);
	}


	@Override
	public Result<?> updateRecordStatusTemplate(RecordTemplateBO recordTemplateBO) {
		int affectedRows = recordTemplateManager.updateRecordTemplate(recordTemplateBO);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public Result<?> appointUpdater(AppointUpdaterRequest request) {
		RecordTemplateBO recordTemplateBO = RecordTemplateConverter.toBO(request);
		recordTemplateBO.setStatus(RecordTemplateConstants.TEMPLATE_STATUS_NOT_MOTIFY);
		int affectedRows = recordTemplateManager.updateRecordTemplate(recordTemplateBO);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public Collection<RecordTemplateBO> pageUpdateRequest(RecordTemplateQuery query) {
		List<RecordTemplateBO> recordTemplateBOS = recordTemplateManager.listRecordTemplate(query);
		List<Long> createUserIds = recordTemplateBOS.stream().map(RecordTemplateBO::getCreateUserId).collect(Collectors.toList());
		userClient.buildByUser(recordTemplateBOS,createUserIds,RecordTemplateBO::getCreateUserId,
				(rtb,ut)->rtb.setCreateUserName(ut.getUserName()));
		return recordTemplateBOS;
	}

	@Override
	public Collection<RecordTemplateBO> pagePrintList(RecordTemplateQuery query) {
		List<RecordTemplateUserGroupBO> recordTemplateUserGroupBOS = recordTemplateUserGroupManager.listRecordTemplateUserGroup(
				RecordTemplateUserGroupQuery.max()
						.userGroupId(UserContextHolder.getUserGroupId()).build());
		Set<Long> templateIds = recordTemplateUserGroupBOS.stream().map(RecordTemplateUserGroupBO::getRecordTemplateId).collect(Collectors.toSet());
		List<RecordTemplateBO> recordTemplateBOS = recordTemplateManager.listRecordTemplateById(templateIds);
		Set<RecordTemplateBO> templateBOS = recordTemplateBOS.stream().filter((b) -> RecordTemplateConstants.TEMPLATE_STATUS_ACTIVE == b.getStatus()).collect(Collectors.toSet());
		return templateBOS;
	}

	@Override
	public Result<?> deleteRecordTemplate(Long recordTemplateId) {
		int affectedRows = recordTemplateManager.deleteRecordTemplate(recordTemplateId);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public Result<GetRecordTemplateResponse> getRecordTemplate(Long recordTemplateId) {
		RecordTemplateBO recordTemplate = recordTemplateManager.getRecordTemplate(recordTemplateId);
		List<RecordTemplateUserGroupBO> recordTemplateUserGroupBOS = recordTemplateUserGroupManager.listRecordTemplateUserGroup(RecordTemplateUserGroupQuery.max().recordTemplateId(recordTemplateId).build());
		List<Long> userGroupIds = recordTemplateUserGroupBOS.stream().map(RecordTemplateUserGroupBO::getUserGroupId).collect(Collectors.toList());
		userGroupClient.buildByUserGroup(recordTemplateUserGroupBOS,userGroupIds,RecordTemplateUserGroupBO::getUserGroupId,(gBO,UTO)->gBO.setUserGroupName(UTO.getUserGroupName()));
		recordTemplate.setGetRecordTemplateUserGroupBOS(recordTemplateUserGroupBOS);
		GetRecordTemplateResponse getRecordTemplateResponse = RecordTemplateConverter.toResponse(recordTemplate);

		//插入文档信息
		Result<GetDocumentResponse> document = documentClient.getDocument(GetDocumentRequest.builder().documentId(recordTemplate.getDocumentId()).build());
		if (document.wasSuccess()) {
			GetDocumentResponse documentResponse = document.getData();
			Result<GetRepositoryResponse> repository = repositoryClient.getRepository(GetRepositoryRequest.builder().repositoryId(documentResponse.getRepositoryId()).build());
			if (repository.wasSuccess()) {
				getRecordTemplateResponse.setBelongTo(repository.getData().getBelongTo());
			}
			getRecordTemplateResponse.setGetDocumentResponse(documentResponse);
		}else{
			return Result.ofErrorRowsAffected();
		}
		return Result.success(getRecordTemplateResponse);
	}

	@Override
	public List<RecordTemplateBO> listRecordTemplateById(Collection<Long> collection) {
		return recordTemplateManager.listRecordTemplateById(collection);
	}

	@Override
	public List<RecordTemplateBO> listRecordTemplate(RecordTemplateQuery query) {
		return recordTemplateManager.listRecordTemplate(query);
	}

	@Override
	public int countRecordTemplate(RecordTemplateQuery query) {
		return recordTemplateManager.countRecordTemplate(query);
	}



}
